#include "include/transmssion/battery_transmssion.h"
#include "include/non_standard_utility.h"
#include "include/paramnonstandard485.h"
#include <QDebug>
Battery_Transmssion::Battery_Transmssion( QObject* parent, ParamNonStandard485* param ) : TransmissionInter( parent, param ) {
    sendDatas[ 0 ] = 0x01;  //地址站号
    sendDatas[ 1 ] = 0x04;  //功能码
    sendDatas[ 2 ] = 0x00;  //寄存器高位字节
    sendDatas[ 3 ] = 0x60;  //寄存器低位字节
    sendDatas[ 4 ] = 0x00;  //读取寄存器数量高位字节
    sendDatas[ 5 ] = 0x44;  //读取寄存器数量低位字节
    QByteArray crc = Non_Standard_Utility::CRC16_ModBus( sendDatas, sendDatas.count() );
    sendDatas.append( crc );
}

Battery_Transmssion::~Battery_Transmssion() {}

void Battery_Transmssion::init( QList< QByteArray >* writeList, int state_ID ) {
    sendDatas[ 0 ] = static_cast< uchar >( state_ID );
}

void Battery_Transmssion::onReadHandler( const QByteArray& readByte ) {
    //    qDebug() << "Battery_Transmssion" << readByte.toHex();
    if ( readByte.size() != 142 ) {
        qCritical() << "电池数据长度异常：data.size()=" << readByte.size();
        return;
    }
    if ( readByte.at( 0 ) != 0x01 && readByte.at( 1 ) != 0x04 ) {
        qCritical() << "电池数据包头格式异常：data.size()=" << readByte.size();
        return;
    }
    readDatas = readByte;
}

void Battery_Transmssion::onAddWriteData( QList< QByteArray >* writeList, const TransmissionInter::TransMissionData& transMissionData ) {}

void Battery_Transmssion::onAddReadData( QList< QByteArray >* readList, int state_ID ) {

    readList->append( sendDatas );
}

QString Battery_Transmssion::GET_Value( EnumBattery Enum ) {
    QString str = "0";

    if ( ( Enum + 3 ) < readDatas.length() ) {
        switch ( Enum ) {
        case EnumBattery::MAX_VOLTAGE:
            str = QString::number( static_cast< double >( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) ) / 1000.0 );
            break;
        case EnumBattery::MIN_VOLTAGE:
            str = QString::number( static_cast< double >( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) ) / 1000.0 );
            break;
        case EnumBattery::MAX_VOLTAGE_NUM:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) );
            break;
        case EnumBattery::MIN_VOLTAGE_NUM:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) );
            break;
        case EnumBattery::MAX_TEMP_TEMP_EXCURSION_VALUE:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) - 40 );
            break;
        case EnumBattery::MIN_TEMP_TEMP_EXCURSION_VALUE:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) - 40 );
            break;
        case EnumBattery::MAX_TEMP_EXCURSION_NUM:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) );
            break;
        case EnumBattery::MIN_TEMP_EXCURSION_NUM:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) );
            break;
        case EnumBattery::CELL1_VOLTAGE:
        case EnumBattery::CELL2_VOLTAGE:
        case EnumBattery::CELL3_VOLTAGE:
        case EnumBattery::CELL4_VOLTAGE:
        case EnumBattery::CELL5_VOLTAGE:
        case EnumBattery::CELL6_VOLTAGE:
        case EnumBattery::CELL7_VOLTAGE:
        case EnumBattery::CELL8_VOLTAGE:
        case EnumBattery::CELL9_VOLTAGE:
        case EnumBattery::CELL10_VOLTAGE:
        case EnumBattery::CELL11_VOLTAGE:
        case EnumBattery::CELL12_VOLTAGE:
        case EnumBattery::CELL13_VOLTAGE:
        case EnumBattery::CELL14_VOLTAGE:
        case EnumBattery::CELL15_VOLTAGE:
        case EnumBattery::CELL16_VOLTAGE:
        case EnumBattery::CELL17_VOLTAGE:
        case EnumBattery::CELL18_VOLTAGE:
        case EnumBattery::CELL19_VOLTAGE:
        case EnumBattery::CELL20_VOLTAGE:
        case EnumBattery::CELL21_VOLTAGE:
        case EnumBattery::CELL22_VOLTAGE:
        case EnumBattery::CELL23_VOLTAGE:
        case EnumBattery::CELL24_VOLTAGE:
        case EnumBattery::CELL25_VOLTAGE:
        case EnumBattery::CELL26_VOLTAGE:
        case EnumBattery::CELL27_VOLTAGE:
        case EnumBattery::CELL28_VOLTAGE:
        case EnumBattery::CELL29_VOLTAGE:
        case EnumBattery::CELL30_VOLTAGE:
        case EnumBattery::CELL31_VOLTAGE:
        case EnumBattery::CELL32_VOLTAGE:
            str = QString::number( static_cast< double >( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) ) / 1000.0 );
            break;
        case EnumBattery::TEMPERATURE1_TEMP_EXCURSION_VALUE:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) - 40 );
            break;
        case EnumBattery::TEMPERATURE2_TEMP_EXCURSION_VALUE:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) - 40 );
            break;
        case EnumBattery::TEMPERATURE3_TEMP_EXCURSION_VALUE:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) - 40 );
            break;
        case EnumBattery::TEMPERATURE4_TEMP_EXCURSION_VALUE:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) - 40 );
            break;
        case EnumBattery::TEMPERATURE5_TEMP_EXCURSION_VALUE:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) - 40 );
            break;
        case EnumBattery::TEMPERATURE6_TEMP_EXCURSION_VALUE:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) - 40 );
            break;
        case EnumBattery::SOC:
            str = QString::number( readDatas[ Enum + 1 ] );
            break;
        case EnumBattery::SOH:
            str = QString::number( readDatas[ Enum + 1 ] );
            break;
        case EnumBattery::PackChaCur:
            str = QString::number( ( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) - 10000 ) / 10.0 );
            break;
        case EnumBattery::PackDisCur:
            str = QString::number( ( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) - 10000 ) / 10.0 );
            break;
        case EnumBattery::ALL_CELL_VOLTAGE:

            str = QString::number( static_cast< double >( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) ) / 10.0 );
            break;
        case EnumBattery::MEASURING_CURRENT:
            str = QString::number( static_cast< double >( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) - 10000 ) / 10.0 );
            break;
        case EnumBattery::gstcSysVar_CellWorkState:
            str = "0x0000" + QString::number( Reinterpret( readDatas[ Enum + 3 ], readDatas[ Enum + 2 ], readDatas[ Enum + 1 ], readDatas[ Enum ] ), 16 );
            break;
        case EnumBattery::gstcSysVar_ShortTime:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) );
            break;
        case EnumBattery::gstcSysVar_ChargingTime:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) );
            break;
        case EnumBattery::gstcSysVar_unSwProtectStatus_word:
            str = "0x0000" + QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ), 16 );
            break;
        case EnumBattery::gstcSysVar_ChargeTime:
            str = QString::number( Reinterpret( readDatas[ Enum + 3 ], readDatas[ Enum + 2 ], readDatas[ Enum + 1 ], readDatas[ Enum ] ) );
            break;
        case EnumBattery::gstcSysVar_DischargeTime:
            str = QString::number( Reinterpret( readDatas[ Enum + 3 ], readDatas[ Enum + 2 ], readDatas[ Enum + 1 ], readDatas[ Enum ] ) );
            break;
        case EnumBattery::gstcSysVar_MaxChargeInterval:
            str = QString::number( Reinterpret( readDatas[ Enum + 3 ], readDatas[ Enum + 2 ], readDatas[ Enum + 1 ], readDatas[ Enum ] ) );
            break;
        case EnumBattery::gstcSysVar_MaxDischargeInterval:
            str = QString::number( Reinterpret( readDatas[ Enum + 3 ], readDatas[ Enum + 2 ], readDatas[ Enum + 1 ], readDatas[ Enum ] ) );
            break;
        case EnumBattery::gstcSysVar_BalancehState:
            str = QString::number( Reinterpret( readDatas[ Enum + 3 ], readDatas[ Enum + 2 ], readDatas[ Enum + 1 ], readDatas[ Enum ] ) );
            break;
        case EnumBattery::gstcSysVar_CyclesTime:
            str = QString::number( Reinterpret( readDatas[ Enum + 1 ], readDatas[ Enum ] ) );
            break;
        }
    }
    return str;
}

bool Battery_Transmssion::getFaultState( QString& result ) {
    // UPDATE 2022.11.29 获取电池异常状态时，先确定数据长度
    if ( readDatas.size() <= gstcSysVar_unSwProtectStatus_word + 1 ) {
        result = "无数据";
        return false;
    }
    short int fault = Reinterpret( readDatas[ gstcSysVar_unSwProtectStatus_word + 1 ], readDatas[ gstcSysVar_unSwProtectStatus_word ] );
    if ( ( fault & 0xff ) == 0x00 ) {
        result = "无故障";
        return false;
    }
    else {
        if ( ( fault & 0x01 ) == 0x01 )
            result = "充电过压报警";
        else if ( ( ( fault >> 1 ) & 0x01 ) == 0x01 )
            result = "放电欠压报警";
        else if ( ( ( fault >> 2 ) & 0x01 ) == 0x01 )
            result = "充电过流报警";
        else if ( ( ( fault >> 3 ) & 0x01 ) == 0x01 )
            result = "放电过流报警1";
        else if ( ( ( fault >> 4 ) & 0x01 ) == 0x01 )
            result = "放电过流报警2";
        else if ( ( ( fault >> 5 ) & 0x01 ) == 0x01 )
            result = "短路报警";
        else if ( ( ( fault >> 6 ) & 0x01 ) == 0x01 )
            result = "充电高温报警";
        else if ( ( ( fault >> 7 ) & 0x01 ) == 0x01 )
            result = "充电低温报警";
        else if ( ( ( fault >> 8 ) & 0x01 ) == 0x01 )
            result = "放电高温报警";
        else if ( ( ( fault >> 9 ) & 0x01 ) == 0x01 )
            result = "放电低温报警";
        else if ( ( ( fault >> 10 ) & 0x01 ) == 0x01 )
            result = "压差故障报警";
        else if ( ( ( fault >> 11 ) & 0x01 ) == 0x01 )
            result = "DC-DC温度报警";
        else if ( ( ( fault >> 12 ) & 0x01 ) == 0x01 )
            result = "SOC低报警";
        else if ( ( ( fault >> 13 ) & 0x01 ) == 0x01 )
            result = "绝缘故障报警";
        return true;
    }
}
short Battery_Transmssion::Reinterpret( char L, char H ) {
    QByteArray by( 2, 0x00 );
    by[ 0 ] = L;
    by[ 1 ] = H;
    return *reinterpret_cast< const short* >( by.data() );
}
int Battery_Transmssion::Reinterpret( char L, char H8, char H16, char H24 ) {
    QByteArray by( 4, 0x00 );
    by[ 0 ] = L;
    by[ 1 ] = H8;
    by[ 2 ] = H16;
    by[ 3 ] = H24;
    return *reinterpret_cast< const int* >( by.data() );
}
